--- conftest.sh.orig	2008-08-28 00:12:01.000000000 -0300
+++ conftest.sh	2008-08-28 01:04:19.000000000 -0300
@@ -40,6 +40,12 @@ if [ -n "$BUILD_PARAMS" ]; then
     CFLAGS="$CFLAGS -D$BUILD_PARAMS"
 fi

+CONFTEST_PREAMBLE="#include <linux/autoconf.h>
+    #if defined(CONFIG_XEN) && \
+        defined(CONFIG_XEN_INTERFACE_VERSION) &&  !defined(__XEN_INTERFACE_VERSION__)
+    #define __XEN_INTERFACE_VERSION__ CONFIG_XEN_INTERFACE_VERSION
+    #endif"
+
 compile_test() {
     case "$1" in
         remap_page_range)
@@ -672,6 +678,121 @@ compile_test() {
             fi
         ;;

+        smp_call_function)
+            #
+            # Determine if the smp_call_function() function is
+            # present and how many arguments it takes.
+            #
+            echo "$CONFTEST_PREAMBLE
+            #include <linux/smp.h>
+            void conftest_smp_call_function(void) {
+            #ifdef CONFIG_SMP
+                smp_call_function();
+            #endif
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                rm -f conftest$$.o
+                echo "#undef NV_SMP_CALL_FUNCTION_PRESENT" >> conftest.h
+                return
+            fi
+
+            echo "$CONFTEST_PREAMBLE
+            #include <linux/smp.h>
+            void conftest_smp_call_function(void) {
+                smp_call_function(NULL, NULL, 0, 0);
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                rm -f conftest$$.o
+                echo "#define NV_SMP_CALL_FUNCTION_PRESENT" >> conftest.h
+                echo "#define NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT 4 " >> conftest.h
+                return
+            fi
+
+            echo "$CONFTEST_PREAMBLE
+            #include <linux/smp.h>
+            void conftest_smp_call_function(void) {
+                smp_call_function(NULL, NULL, 0);
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                rm -f conftest$$.o
+                echo "#define NV_SMP_CALL_FUNCTION_PRESENT" >> conftest.h
+                echo "#define NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT 3 " >> conftest.h
+                return
+            else
+                echo "#error smp_call_function() conftest failed!" >> conftest.h
+            fi
+        ;;
+
+        on_each_cpu)
+            #
+            # Determine if the on_each_cpu() function is present
+            # and how many arguments it takes.
+            #
+            echo "$CONFTEST_PREAMBLE
+            #include <linux/smp.h>
+            void conftest_on_each_cpu(void) {
+            #ifdef CONFIG_SMP
+                on_each_cpu();
+            #endif
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                rm -f conftest$$.o
+                echo "#undef NV_ON_EACH_CPU" >> conftest.h
+                return
+            fi
+
+            echo "$CONFTEST_PREAMBLE
+            #include <linux/smp.h>
+            void conftest_on_each_cpu(void) {
+                on_each_cpu(NULL, NULL, 0, 0);
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                rm -f conftest$$.o
+                echo "#define NV_ON_EACH_CPU_PRESENT" >> conftest.h
+                echo "#define NV_ON_EACH_CPU_ARGUMENT_COUNT 4 " >> conftest.h
+                return
+            fi
+
+            echo "$CONFTEST_PREAMBLE
+            #include <linux/smp.h>
+            void conftest_on_each_cpu(void) {
+                on_each_cpu(NULL, NULL, 0);
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                rm -f conftest$$.o
+                echo "#define NV_ON_EACH_CPU_PRESENT" >> conftest.h
+                echo "#define NV_ON_EACH_CPU_ARGUMENT_COUNT 3 " >> conftest.h
+                return
+            else
+                echo "#error on_each_cpu() conftest failed!" >> conftest.h
+            fi
+        ;;
+
+
     esac
 }

@@ -1203,11 +1324,21 @@ case "$5" in
         # Run a series of compile tests to determine the set of interfaces
         # and features available in the target kernel.
         #
+        FILES="linux/semaphore.h"
         shift 5

         rm -f conftest.h
         for i in $*; do compile_test $i; done

+        for FILE in $FILES; do
+            FILE_DEFINE=NV_`echo $FILE | tr '/.' '_' | tr 'a-z' 'A-Z'`_PRESENT
+            if [ -f $HEADERS/$FILE -o -f $OUTPUT/include/$FILE ]; then
+                echo "#define $FILE_DEFINE" >> conftest.h
+            else
+                echo "#undef $FILE_DEFINE" >> conftest.h
+            fi
+        done
+
         if [ -n "$SHOW_COMPILE_TEST_RESULTS" -a -f conftest.h ]; then
             cat conftest.h
         fi
--- Makefile.kbuild.orig	2008-08-28 00:26:41.000000000 -0300
+++ Makefile.kbuild	2008-08-28 00:30:01.000000000 -0300
@@ -186,13 +186,16 @@ ifneq ($(PATCHLEVEL), 4)
 	BREAKPOINT \
 	acpi_device_ops \
 	acquire_console_sem \
-	kmem_cache_create
+	kmem_cache_create \
+	on_each_cpu \
+	smp_call_function
 else
  COMPILE_TESTS = \
 	remap_page_range \
 	vmap \
 	change_page_attr \
-	i2c_adapter
+	i2c_adapter \
+	smp_call_function
 endif

 #
--- Makefile.nvidia.orig	2008-08-28 00:30:18.000000000 -0300
+++ Makefile.nvidia	2008-08-28 00:30:35.000000000 -0300
@@ -62,7 +62,8 @@ COMPILE_TESTS = \
 	remap_page_range \
 	vmap \
 	change_page_attr \
-	i2c_adapter
+	i2c_adapter \
+	smp_call_function

 DEFINES+=$(EXTRA_DEFINES)

--- nv.c.orig	2008-08-28 00:08:18.000000000 -0300
+++ nv.c	2008-08-28 01:00:05.000000000 -0300
@@ -832,8 +832,8 @@ static void __nv_setup_pat_entries(void
     unsigned long eflags;

 #if defined(CONFIG_HOTPLUG_CPU)
-    unsigned int cpu = (NvUPtr)info;
-    if ((cpu != 0) && (cpu != smp_processor_id()))
+    int cpu = (NvUPtr)info;
+    if ((cpu != 0) && (cpu != (int)smp_processor_id()))
         return;
 #endif

@@ -858,8 +858,8 @@ static void __nv_restore_pat_entries(voi
     unsigned long eflags;

 #if defined(CONFIG_HOTPLUG_CPU)
-    unsigned int cpu = (NvUPtr)info;
-    if ((cpu != 0) && (cpu != smp_processor_id()))
+    int cpu = (NvUPtr)info;
+    if ((cpu != 0) && (cpu != (int)smp_processor_id()))
         return;
 #endif

@@ -1179,27 +1179,27 @@ failed:
 static int
 nv_kern_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
-    unsigned int cpu = (NvUPtr)hcpu;
-
+    unsigned int cpu = get_cpu();
+
     switch (action)
     {
         case CPU_DOWN_FAILED:
         case CPU_ONLINE:
-            if (get_cpu() == cpu)
+            if (cpu == (NvUPtr)hcpu)
                 __nv_setup_pat_entries(NULL);
             else
-                smp_call_function(__nv_setup_pat_entries, hcpu, 1, 1);
-            put_cpu();
+                NV_SMP_CALL_FUNCTION(__nv_setup_pat_entries, hcpu, 1);
             break;
         case CPU_DOWN_PREPARE:
-            if (get_cpu() == cpu)
+            if (cpu == (NvUPtr)hcpu)
                 __nv_restore_pat_entries(NULL);
             else
-                smp_call_function(__nv_restore_pat_entries, hcpu, 1, 1);
-            put_cpu();
+                NV_SMP_CALL_FUNCTION(__nv_restore_pat_entries, hcpu, 1);
             break;
     }

+    put_cpu();
+
     return NOTIFY_OK;
 }

--- nv-linux.h.orig	2008-08-28 00:13:57.000000000 -0300
+++ nv-linux.h	2008-08-28 01:05:50.000000000 -0300
@@ -103,7 +103,11 @@
 #endif

 #include <linux/spinlock.h>
+#if defined(NV_LINUX_SEMAPHORE_H_PRESENT)
+#include <linux/semaphore.h>
+#else
 #include <asm/semaphore.h>
+#endif
 #include <linux/completion.h>
 #include <linux/highmem.h>

@@ -609,6 +613,46 @@ static inline unsigned long nv_virt_to_p

 #endif /* !defined NVWATCH */

+#if defined(NV_SMP_CALL_FUNCTION_PRESENT)
+#if (NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT == 4)
+#define NV_SMP_CALL_FUNCTION(func, info, wait)               \
+    ({                                                       \
+        int __ret = smp_call_function(func, info, 1, wait);  \
+        __ret;                                               \
+     })
+#elif (NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT == 3)
+#define NV_SMP_CALL_FUNCTION(func, info, wait)               \
+    ({                                                       \
+        int __ret = smp_call_function(func, info, wait);     \
+        __ret;                                               \
+     })
+#else
+#error "NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT value unrecognized!"
+#endif
+#elif defined(CONFIG_SMP)
+#error "NV_SMP_CALL_FUNCTION() undefined (smp_call_function() unavailable)!"
+#endif
+
+#if defined(NV_ON_EACH_CPU_PRESENT)
+#if (NV_ON_EACH_CPU_ARGUMENT_COUNT == 4)
+#define NV_ON_EACH_CPU(func, info, wait)               \
+    ({                                                 \
+        int __ret = on_each_cpu(func, info, 1, wait);  \
+        __ret;                                         \
+     })
+#elif (NV_ON_EACH_CPU_ARGUMENT_COUNT == 3)
+#define NV_ON_EACH_CPU(func, info, wait)               \
+    ({                                                 \
+        int __ret = on_each_cpu(func, info, wait);     \
+        __ret;                                         \
+     })
+#else
+#error "NV_ON_EACH_CPU_ARGUMENT_COUNT value unrecognized!"
+#endif
+#elif !defined(KERNEL_2_4) && defined(CONFIG_SMP)
+#error "NV_ON_EACH_CPU() undefined (on_each_cpu() unavailable)!"
+#endif
+
 static inline int nv_execute_on_all_cpus(void (*func)(void *info), void *info)
 {
     int ret = 0;
@@ -618,13 +662,13 @@ static inline int nv_execute_on_all_cpus
 #if defined(preempt_disable)
     preempt_disable();
 #endif
-    ret = smp_call_function(func, info, 1, 1);
+    ret = NV_SMP_CALL_FUNCTION(func, info, 1);
     func(info);
 #if defined(preempt_enable)
     preempt_enable();
 #endif
 #else
-    ret = on_each_cpu(func, info, 1, 1);
+    ret = NV_ON_EACH_CPU(func, info, 1);
 #endif
     return ret;
 }
--- os-interface.c.orig	2008-08-28 00:20:50.000000000 -0300
+++ os-interface.c	2008-08-28 01:21:49.000000000 -0300
@@ -48,7 +48,7 @@ RM_STATUS NV_API_CALL os_raise_smp_barri
 #endif
     local_bh_disable();
     atomic_set(&os_smp_barrier, 1);
-    ret = smp_call_function(ipi_handler, NULL, 1, 0);
+    ret = NV_SMP_CALL_FUNCTION(ipi_handler, NULL, 0);
 #endif
     return (ret == 0) ? RM_OK : RM_ERROR;
 }

--- os-interface.c.orig	2008-08-28 13:11:52.000000000 -0300
+++ os-interface.c	2008-08-28 13:12:33.000000000 -0300
@@ -632,7 +632,7 @@ RM_STATUS NV_API_CALL os_kill_process(
     U032 sig
 )
 {
-    return kill_proc(pid, sig, 1) ? RM_ERR_OPERATING_SYSTEM : RM_OK;
+    return /*kill_proc(pid, sig, 1) ?*/ RM_ERR_OPERATING_SYSTEM /*: RM_OK*/;
 }

 /*******************************************************************************/
